package com.wms.service.impl;

import com.wms.dto.AddStkByLocationDTO;
import com.wms.dto.WarehouseDTO;
import com.wms.dto.LocationDTO;
import com.wms.dto.TaskDetailDTO;
import com.wms.entity.StockTakingTask;
import com.wms.entity.StockTakingTaskDetailGroup;
import com.wms.mapper.*;
import com.wms.service.ReviewAdjustmentsDetailGroupService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
import com.wms.entity.StkWarehouse;
import com.wms.entity.StkLocation;

@Service
public class ReviewAdjustmentsDetailGroupServiceImpl implements ReviewAdjustmentsDetailGroupService {

    @Autowired
    ReviewAdjustmentsDetailGroupMapper reviewAdjustmentsDetailGroupMapper;

    @Autowired
    SaveTaskDetailActualQtyMapper saveTaskDetailActualQtyMapper;

    @Autowired
    StockTakingTaskMapper stockTakingTaskMapper;

    @Autowired
    AddStkByLocationMapper addStkByLocationMapper;

    @Autowired
    StockTakingTaskDetailGroupMapper stockTakingTaskDetailGroupMapper;



    /**
     * 根据任务编码查询审核调整单详情(分组)
     * @param code
     * @return
     */
    @Override
    public StockTakingTaskDetailGroup queryReviewAdjustmentsDetailGroup(String code) {
        // 1. 查询任务基本信息
        StockTakingTaskDetailGroup taskDetail = reviewAdjustmentsDetailGroupMapper.queryReviewAdjustmentsDetailGroup(code);
        if (taskDetail == null) {
            return null;
        }

        // 2. 查询库区信息
        List<WarehouseDTO> warehouses = reviewAdjustmentsDetailGroupMapper.queryWarehouse(taskDetail.getTaskId());

        // 3. 为每个库区查询货架信息
        for (WarehouseDTO warehouse : warehouses) {
            List<LocationDTO> locations = reviewAdjustmentsDetailGroupMapper.queryLocation(taskDetail.getTaskId(), warehouse.getId());

            // 4. 为每个货架查询物品列表
            for (LocationDTO location : locations) {
                List<TaskDetailDTO> items = reviewAdjustmentsDetailGroupMapper.queryTaskDetail(taskDetail.getTaskId(), location.getId());
                location.setTaskDetailDTOList(items);
            }

            warehouse.setLocationDTOList(locations);
        }

        // 5. 设置库区列表到任务详情中
        taskDetail.setWarehouseList(warehouses);

        return taskDetail;
    }

    /**
     * 更新审核状态为完成调整(对应的status改为已完成盘点)
     * @param code
     * @param auditOpinion
     * @return
     */
    @Override
    public int updateTaskAuditStatusByFinishReview(String code, String auditOpinion,int auditUserId) {
        return reviewAdjustmentsDetailGroupMapper.updateTaskAuditStatusByFinishReview(code, auditOpinion,auditUserId);
    }


    /**
     * 打回重盘
     * @param taskCode
     * @param auditOpinion
     * @param userId
     * @return
     */
    @Override
    public int updateTaskAuditStatusByNoFinishReview(String taskCode, String auditOpinion, int userId) {
        //1.根据任务编码查询任务id
        int taskId=saveTaskDetailActualQtyMapper.queryTaskDetailById(taskCode);
        if (taskId==0){
            throw new RuntimeException("任务编码不存在");
        }
        int result3=0;
        int result4=0;
        //2.判断userId是否和盘点任务userId相同
        if(userId==reviewAdjustmentsDetailGroupMapper.queryUserIdByTaskCode(taskCode)){
            //2.1相同则把状态改为待盘点 auditStatus 改为打回重盘  actual_qty diff_qty breakage 清0
            int result1=stockTakingTaskMapper.updateTaskStatusAndAuditStatus(taskId);
            if (result1!=1){
                throw new RuntimeException("任务状态更新失败");
            }
            int result2=reviewAdjustmentsDetailGroupMapper.updateRasDetailActualAndDiffAndBreakage(taskId);
            if (result2!=1){
                throw new RuntimeException("盘点任务详情更新失败");
            }
            // 更新原任务的审核意见
            int result5=reviewAdjustmentsDetailGroupMapper.updateTaskAuditOpinion(taskId, auditOpinion);
            if (result5!=1){
                throw new RuntimeException("更新审核意见失败");
            }
            // 当userId相同时，直接返回成功
            return 1;
        }else {
            //2.2查询原任务信息
            StockTakingTask oldTask=stockTakingTaskMapper.queryTaskById(taskId);
            
            //2.3更新原任务状态为已完成、已作废、打回重盘
            int result0=stockTakingTaskMapper.updateTaskStatusForDifferentUser(taskId);
            if (result0!=1){
                throw new RuntimeException("原任务状态更新失败");
            }
            
            //2.4更新原任务的审核意见
            int result6=reviewAdjustmentsDetailGroupMapper.updateTaskAuditOpinion(taskId, auditOpinion);
            if (result6!=1){
                throw new RuntimeException("更新原任务审核意见失败");
            }
            
            //2.5生成新的任务编号
            String newTaskCode=generateNewTaskNum(oldTask.getCode());
            //2.6生成新的任务
            AddStkByLocationDTO addStkByLocationDTO = new AddStkByLocationDTO();
            // 手动复制需要的字段，而不是使用BeanUtils.copyProperties
            addStkByLocationDTO.setCode(newTaskCode); // 使用生成的新任务编号
            addStkByLocationDTO.setTaskName(oldTask.getTaskName()); // 复制任务名称
            addStkByLocationDTO.setStockId(oldTask.getStockId()); // 复制仓库ID
            addStkByLocationDTO.setStockName(oldTask.getStockName()); // 复制仓库名称
            addStkByLocationDTO.setNote(oldTask.getNote()); // 复制备注
            addStkByLocationDTO.setTaskType(oldTask.getTaskType()); // 复制任务类型
            addStkByLocationDTO.setUserId(userId);
            addStkByLocationDTO.setTakeDate(oldTask.getTakeDate().toString()); // 复制原任务的盘点时间
            result3 = addStkByLocationMapper.AddStkByLocation(addStkByLocationDTO);

            //3复制任务详情记录
            result4 =stockTakingTaskDetailGroupMapper.copyTaskDetails(taskCode,newTaskCode,userId);
            
            //4.生成新任务的area和loc表数据
            if (result3 > 0 && result4 > 0) {
                int newTaskId = addStkByLocationDTO.getId();
                // 复制原任务的area数据
                copyTaskAreaData(taskId, newTaskId);
                // 复制原任务的loc数据
                copyTaskLocData(taskId, newTaskId);
            }
        }

        //if userId=其他id 生成新的盘点任务
        return (result3>0 && result4>0)?1:0;
    }
    
    /**
     * 生成新的任务编号
     * @param oldTaskNum 原任务编号
     * @return 新任务编号
     */
    private String generateNewTaskNum(String oldTaskNum) {
        // 生成更短的任务编号：原编号 + "_RE" + 6位随机数
        String randomSuffix = String.valueOf((int)(Math.random() * 900000) + 100000);
        return oldTaskNum + "_RE" + randomSuffix;
    }
    
    /**
     * 复制任务库区数据
     * @param oldTaskId 原任务ID
     * @param newTaskId 新任务ID
     */
    private void copyTaskAreaData(int oldTaskId, int newTaskId) {
        // 查询原任务的库区数据
        List<WarehouseDTO> oldAreas = reviewAdjustmentsDetailGroupMapper.queryWarehouse(oldTaskId);
        for (WarehouseDTO area : oldAreas) {
            // 创建StkWarehouse对象并插入新任务的库区数据
            StkWarehouse warehouse = new StkWarehouse();
            warehouse.setTaskId(newTaskId);
            warehouse.setAreaId(area.getId());
            warehouse.setArea(area.getName());
            warehouse.setTaskNum(area.getTaskNum());
            warehouse.setFinishedNum(0);
            warehouse.setUnfinishedNum(area.getTaskNum());
            addStkByLocationMapper.saveStkWarehouse(warehouse);
        }
    }
    
    /**
     * 复制任务货位数据
     * @param oldTaskId 原任务ID
     * @param newTaskId 新任务ID
     */
    private void copyTaskLocData(int oldTaskId, int newTaskId) {
        // 查询原任务的库区数据
        List<WarehouseDTO> oldAreas = reviewAdjustmentsDetailGroupMapper.queryWarehouse(oldTaskId);
        for (WarehouseDTO area : oldAreas) {
            // 查询该库区下的货位数据
            List<LocationDTO> oldLocations = reviewAdjustmentsDetailGroupMapper.queryLocation(oldTaskId, area.getId());
            for (LocationDTO location : oldLocations) {
                // 创建StkLocation对象并插入新任务的货位数据
                StkLocation stkLocation = new StkLocation();
                stkLocation.setTaskId(newTaskId);
                stkLocation.setAreaId(area.getId());
                stkLocation.setLocationId(location.getId());
                stkLocation.setLocation(location.getLocation());
                stkLocation.setTaskNum(location.getTaskNum());
                stkLocation.setFinishedNum(0);
                stkLocation.setUnfinishedNum(location.getTaskNum());
                addStkByLocationMapper.saveStkLocation(stkLocation);
            }
        }
    }
}
